package clientServer;

import static org.junit.Assert.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import message.AuthenticationRequestMessage;
import message.AuthenticationResponseMessage;
import message.Message;
import message.UpdateDataRequestMessage;
import message.UpdateDataResponseMessage;
import message.messageFactory.MessageFactory;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import server.Server;

public class ClientServerTest
{
	private static Server server;
	private static MessageFactory factory;
	private static Socket socket;
	private static PrintWriter out;
	private static BufferedReader in;
	
	@BeforeClass
	public static void startUp() throws InstantiationException, UnknownHostException, IOException
	{
		factory = MessageFactory.getInstance();
		server = new Server("config.xml");
		
		Thread thread = new Thread(new Runnable()
		{
			@Override
			public void run()
			{
				server.run();
			}
		});
		
		thread.start();
		
		while (!server.isReady())
		{
			try
			{
				Thread.sleep(10);
			}
			catch (InterruptedException e) {}
		}
		
		socket = new Socket("127.0.0.1", 62455);
		out = new PrintWriter(socket.getOutputStream(), true);
		in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
	}
	@After
	public void afterTest()
	{
		UpdateDataRequestMessage request = new UpdateDataRequestMessage();
		
		request.setUsername("test");
		request.setPassword("test");
		
		out.println(factory.serializeMessage(request));
	}
	@AfterClass
	public static void cleanUp()
	{
		server.stop();
		
		while (server.isRunning())
		{
			try
			{
				Thread.sleep(10);
			}
			catch (InterruptedException e) {}
		}
	}
	@Test
	public void authenticationTest() throws UnknownHostException, IOException
	{
		AuthenticationRequestMessage request = new AuthenticationRequestMessage();
		AuthenticationResponseMessage expectedResponse = new AuthenticationResponseMessage();
		
		request.setUsername("test");
		request.setPassword("test");
		expectedResponse.setSuccess(true);
		
		out.println(factory.serializeMessage(request));
		
		Message response = factory.unserializeMessage(in.readLine());
		
		assertEquals(expectedResponse, response);
		
		request = new AuthenticationRequestMessage();
		expectedResponse = new AuthenticationResponseMessage();
		
		request.setUsername("incorrectUsername");
		request.setPassword("test");
		expectedResponse.setSuccess(false);
		
		out.println(factory.serializeMessage(request));
		
		response = factory.unserializeMessage(in.readLine());
		
		assertEquals(expectedResponse, response);
		
		request = new AuthenticationRequestMessage();
		
		request.setUsername("test");
		request.setPassword("incorrectPassword");
		
		out.println(factory.serializeMessage(request));
		
		response = factory.unserializeMessage(in.readLine());
		
		assertEquals(expectedResponse, response);
	}
	@Test
	public void updateTest() throws IOException
	{
		UpdateDataRequestMessage request = new UpdateDataRequestMessage();
		UpdateDataResponseMessage expectedResponse = new UpdateDataResponseMessage();
		
		request.setUsername("test");
		request.setPassword("test2");
		
		expectedResponse.setSuccess(true);
		
		out.println(factory.serializeMessage(request));
		
		Message response = factory.unserializeMessage(in.readLine());
		
		System.out.println(response.getClass());
		
		assertEquals(expectedResponse, response);
	}
}
